package com.zcxy.fast.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.DES;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.zcxy.fast.entity.SysAttachment;
import com.zcxy.fast.exception.BusinessException;
import com.zcxy.fast.service.ISysAttachmentService;
import com.zcxy.fast.utils.SpringContextHolder;
import com.zcxy.fast.utils.StringUtils;
import io.minio.MinioClient;
import io.minio.ObjectStat;
import io.minio.PutObjectOptions;
import io.minio.Result;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * @author zcc
 * @version 1.0.0
 * @ClassName MonioUtil.java
 * @Description TODO
 * @createTime 2020年07月01日 10:59:00
 */
@Slf4j
public class MonioUtil {


    public static final String MINIO_BUCKET = "fast";

    public static final  String SALT="fast-attach";


    /**
     * 根据业务id查询 文件服务器上的文件-----暂时用不到 改为私有
     */
    private static List<Object> list(String bussnessId) throws Exception {
        MinioClient minioClient = SpringContextHolder.getBean(MinioClient.class);
        Iterable<Result<Item>> myObjects = minioClient.listObjects(MINIO_BUCKET, bussnessId);
        Iterator<Result<Item>> iterator = myObjects.iterator();
        List<Object> items = new ArrayList<>();
        String format = "{'fileName':'%s','fileSize':'%s'}";
        while (iterator.hasNext()) {
            Item item = iterator.next().get();
            items.add(JSON.parse(String.format(format, item.objectName(), formatFileSize(item.size()))));
        }
        return items;
    }

    /**
     * 根据业务id上传附件
     *
     * @param file
     * @param
     * @return
     */
    public static SysAttachment Upload(MultipartFile file, String fileUuid) {
        MultipartFile[] multipartFiles = new MultipartFile[1];
        multipartFiles[0] = file;
        return MonioUtil.batchUpload(multipartFiles, fileUuid).get(0);
    }

    /**
     * 根据业务id上传附件
     *
     * @param file
     * @param
     * @return
     */
    public static List<SysAttachment> batchUpload(MultipartFile[] file, String fileUuid) {
        MinioClient minioClient = SpringContextHolder.getBean(MinioClient.class);
        //根据时间生成uuid
        if (StringUtils.isEmpty(fileUuid)) {
            //根据时间生成uuid
            fileUuid = DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN) + "-" + RandomUtil.randomString(2);
        }
        List<SysAttachment> sysAttachments = new ArrayList<>();
        for (MultipartFile multipartFile : file) {
            SysAttachment sysAttachment = new SysAttachment();
            sysAttachment.setFileUuid(fileUuid);
            sysAttachment.setFileName(multipartFile.getOriginalFilename());

            sysAttachment.setFileOssUrl("/sys/download/" +fileUuid + "-" + multipartFile.getOriginalFilename());
            try {
                InputStream in = multipartFile.getInputStream();
                //上传到文件服务器文件加密
                DES des = SecureUtil.des(MonioUtil.SALT.getBytes());
                String encrypt = des.encryptHex(fileUuid + "-" + multipartFile.getOriginalFilename());
                minioClient.putObject(MINIO_BUCKET, encrypt, in, new PutObjectOptions(in.available(), -1));
                in.close();
            } catch (Exception e) {
                log.error(e.getMessage());

            }
            sysAttachments.add(sysAttachment);
        }

        return sysAttachments;
    }


    /**
     * 文件下载
     *
     * @param response
     * @param fileName
     */
    public static void download(HttpServletResponse response, String fileName) {

        InputStream in = null;
        MinioClient minioClient = SpringContextHolder.getBean(MinioClient.class);
        try {
            ObjectStat stat = minioClient.statObject(MINIO_BUCKET, fileName);
            response.setContentType(stat.contentType());
                   response.setHeader("Content-Length", "" + stat.length());
            in = minioClient.getObject(MINIO_BUCKET, fileName);
            IOUtils.copy(in, response.getOutputStream());
            DES des = SecureUtil.des(MonioUtil.SALT.getBytes());
            try {
                String encrypt = des.decryptStr(fileName);
                fileName=encrypt;
            } catch (Exception e) {
                e.printStackTrace();
            }
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));


        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error(e.getMessage());
                }
            }
        }
    }

    public static byte[] download(String fileName) {

        InputStream in = null;
        MinioClient minioClient = SpringContextHolder.getBean(MinioClient.class);
        try {
            ObjectStat stat = minioClient.statObject(MINIO_BUCKET, fileName);
            in = minioClient.getObject(MINIO_BUCKET, fileName);
            return IOUtils.toByteArray(in);
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BusinessException(e.getMessage());
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    log.error(e.getMessage());
                }
            }
        }
    }

    private static String formatFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString;
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + " B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + " KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + " MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + " GB";
        }
        return fileSizeString;
    }

    /**
     * 同步保存业务附件表
     *
     * @param sysAttachments
     */
    public static void saveSysattachments(List<SysAttachment> sysAttachments) {
        //删除掉当前uuid的文件
        if (CollectionUtil.isNotEmpty(sysAttachments)) {
            String uuid = sysAttachments.get(0).getFileUuid();
            ISysAttachmentService sysAttachmentMapper = SpringContextHolder.getBean(ISysAttachmentService.class);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("file_uuid", uuid);
            sysAttachmentMapper.getBaseMapper().delete(queryWrapper);
            sysAttachmentMapper.saveOrUpdateBatch(sysAttachments);
        }
    }

    /**
     * 同步保存业务附件表
     *
     * @param
     */
    public static void saveSysattachment(SysAttachment sysAttachment) {
        //删除掉当前uuid的文件
        if (sysAttachment != null) {
            String uuid = sysAttachment.getFileUuid();
            ISysAttachmentService sysAttachmentMapper = SpringContextHolder.getBean(ISysAttachmentService.class);
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("file_uuid", uuid);
            sysAttachmentMapper.getBaseMapper().delete(queryWrapper);
            sysAttachmentMapper.saveOrUpdate(sysAttachment);
        }
    }

    /**
     * 查询业务表的所有附件
     *
     * @param uuid
     */
    public static List<SysAttachment> getSysattachmentsByUUid(String uuid) {
        ISysAttachmentService sysAttachmentMapper = SpringContextHolder.getBean(ISysAttachmentService.class);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("file_uuid", uuid);
        return sysAttachmentMapper.getBaseMapper().selectList(queryWrapper);
    }

    public static String getFileType(String filename) {
        int begin = filename.lastIndexOf(".");
        int last = filename.length();
        //获得文件后缀名
        return filename.substring(begin+1, last);
    }


}
